/**
 * 版权所有 @鸿名物联 
 * 未经授权，禁止侵权和商业，违法必究
 * 联系QQ：2224313811 
 * 
 */
package com.lp.controller.iot;

import com.lp.bo.*;
import com.lp.cache.CacheName;
import com.lp.cache.ProCacheUtil;
import com.lp.cfg.ProConfig;
import com.lp.common.Code;
import com.lp.common.Code.ResponseCode;
import com.lp.common.CodeIot;
import com.lp.common.RequestURLIOT;
import com.lp.controller.BaseController;
import com.lp.service.IotNodeInfoService;
import com.lp.util.ObjectUtil;
import com.lp.util.ResultMapUtils;
import com.lp.util.iot.ProtocolUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Controller
public class IotNodeInfoController extends BaseController {

	@Autowired
	private IotNodeInfoService iotNodeInfoService ;
	
	/**
	 * 检索
	 * @param response
	 * @param 
	 * @return
	 */
	@RequestMapping(method = RequestMethod.POST, value = RequestURLIOT.NodeInfo.NODE_INFO_PAGE)
	public ModelAndView selectPage(HttpServletResponse response, 
			@RequestHeader(value = ResultMapUtils.USER_KEY, required = true) String userKey ,
			@RequestBody IotNodeInfoBO obj,
			@RequestParam(required=false) Integer pageSize ,
			@RequestParam Integer paged ) {
		Map<String, Object> resultMap = getResultMap();
		try {
			UserInfoBO user = getUserInfoByUserKey(userKey);
			obj.setUser_id(user.getId());
			resultMap = service.selectPageList("IotNodeInfo.selectPage",getPageBean(paged,pageSize), obj);	
		} catch (Exception e) {
			exception(e,resultMap, obj);
		}
		return getModelAndView(response, resultMap);
	}
	
	/**
	 * 设备统计
	 * @param response
	 * @param userKey
	 * @param obj
	 * @return
	 */
	@RequestMapping(method = RequestMethod.POST, value = RequestURLIOT.NodeInfo.NODE_STATISTIC)
	public ModelAndView selectStatisticNode(HttpServletResponse response, 
			@RequestHeader(value = ResultMapUtils.USER_KEY, required = true) String userKey ,
			@RequestBody IotNodeInfoBO obj) {
		Map<String, Object> resultMap = getResultMap();
		try {
			UserInfoBO user = getUserInfoByUserKey(userKey);
			obj.setUser_id(user.getId()); 
			resultMap = service.selectList("IotNodeInfo.selectStatisticNodeInfo", obj) ;
		} catch (Exception e) {
			exception(e,resultMap, obj);
		}
		return getModelAndView(response, resultMap);
	}
	
	/**
	 * 检索 - 管理员使用
	 * @param response
	 * @param 
	 * @return
	 */
	@RequestMapping(method = RequestMethod.POST, value = RequestURLIOT.NodeInfo.ADMIN_NODE_INFO_PAGE)
	public ModelAndView selectALLNodePage(HttpServletResponse response, 
			@RequestHeader(value = ResultMapUtils.USER_KEY, required = true) String userKey ,
			@RequestBody IotNodeInfoBO obj,
			@RequestParam(required=false) Integer pageSize ,
			@RequestParam Integer paged ) {
		Map<String, Object> resultMap = getResultMap();
		try {
			UserInfoBO user = getUserInfoByUserKey(userKey);
			if(user.getType() == Code.UserType.SUPER ){
				resultMap = service.selectPageList("IotNodeInfo.selectPage",getPageBean(paged,pageSize), obj);					
			}
		} catch (Exception e) {
			exception(e,resultMap, obj);
		}
		return getModelAndView(response, resultMap);
	}
	
	/**
	 * 设备仓库 
	 * 未使用设备
	 * @param response
	 * @param 
	 * @return
	 */
	@RequestMapping(method = RequestMethod.POST, value = RequestURLIOT.NodeInfo.ADMIN_UNUSED_NODES)
	public ModelAndView selectALLUnusedDevice(HttpServletResponse response, 
			@RequestHeader(value = ResultMapUtils.USER_KEY, required = true) String userKey ,
			@RequestBody IotNodeInfoBO obj,
			@RequestParam(required=false) Integer pageSize ,
			@RequestParam Integer paged ) {
		Map<String, Object> resultMap = getResultMap();
		try {
			UserInfoBO user = getUserInfoByUserKey(userKey);
			if(user.getType() == Code.UserType.SUPER ){
				resultMap = service.selectPageList("IotNodeInfo.selectUnUsedNode",getPageBean(paged,pageSize), obj);					
			}
		} catch (Exception e) {
			exception(e,resultMap, obj);
		}
		return getModelAndView(response, resultMap);
	}
	
	/**
	 * 插入
	 * @param response
	 * @param 
	 * @return
	 */
	@RequestMapping(method = RequestMethod.POST, value = RequestURLIOT.NodeInfo.NODE_INFO )
	public ModelAndView save(HttpServletResponse response, 
			@RequestHeader(value = ResultMapUtils.USER_KEY, required = true) String userKey ,
			@RequestBody IotNodeInfoBO obj ) {
		Map<String, Object> resultMap = getResultMap();
		try {
			if( ObjectUtil.isNotEmpty(obj.getScene_id()) ){
				IotNodeInfoBO nodeInfo = ProCacheUtil.getCache(CacheName.NODEINFO_DEVICECODE, obj.getDevice_code()) ;
				// 判断device_code是否重复
				if(ObjectUtil.isNotEmpty(nodeInfo)){
					putStatusCode(resultMap, ResponseCode.IotInfo.DEVICE_CODE_EXIST);
				} else {
					IotNodeInfoBO iotNodeInfoBO = (IotNodeInfoBO)getData(service.selectOne("IotNodeInfo.selectMaxCode", obj.getCq_hazard_code(), obj.getCq_equip_type())) ;
					if (ObjectUtil.isNotEmpty(iotNodeInfoBO)) {
						String str = iotNodeInfoBO.getCq_equip_code().substring(iotNodeInfoBO.getCq_equip_code().length() - 3);
						int num = Integer.parseInt(str) + 1;
						obj.setCq_equip_code(obj.getCq_hazard_code() + obj.getCq_equip_type() + String.format("%03d", num));
					} else {
						obj.setCq_equip_code(obj.getCq_hazard_code() + obj.getCq_equip_type() + "001");
					}
					UserInfoBO user = getUserInfoByUserKey(userKey);
					obj.setIot_node_status(CodeIot.DEVICE_STATUS.UNCONTECT);
					obj.setCq_equip_status(0);
					obj.setMtime(new Date());
					obj.setCq_create_date(new Date());
					obj.setCq_create_by(user.getName());
					obj.setCq_update_date(new Date());
					obj.setCq_update_by(user.getName());
					resultMap = iotNodeInfoService.saveNodeInfo(obj);
				}
			}else{
				putStatusCode(resultMap, ResponseCode.SystemCode.PARAM_ERROR);
			}
			if( isOk(resultMap) ){
				ProCacheUtil.addCache(CacheName.NODEINFO, obj.getId().toString(), obj);
				ProCacheUtil.addCache(CacheName.NODEINFO_DEVICECODE, obj.getDevice_code(), obj);
			}
		} catch (Exception e) {
			exception(e,resultMap, obj);
		}
		return getModelAndView(response, resultMap);
	}
	
	/**
	 * 网关下数据的同步
	 */
	@RequestMapping(method = RequestMethod.PUT, value = RequestURLIOT.NodeInfo.NODE_DATA_INFO_SYNC)
	public ModelAndView syncNodeStatus(HttpServletResponse response, 
			@RequestBody IotNodeInfoBO obj ) {
		Map<String, Object> resultMap = getResultMap();
		try {
			resultMap = iotNodeInfoService.syncData(obj);
		} catch (Exception e) {
			exception(e,resultMap, obj);
		}
		return getModelAndView(response, resultMap);
	}
	
	/**
	 * 根据设备仓库中的设备号添加
	 * @param response
	 * @param userKey
	 * @param obj
	 * @return
	 */
	@RequestMapping(method = RequestMethod.POST, value = RequestURLIOT.NodeInfo.NODE_BIND)
	public ModelAndView deviceAdd(HttpServletResponse response, 
			@RequestHeader(value = ResultMapUtils.USER_KEY, required = true) String userKey ,
			@RequestBody IotNodeInfoBO obj ) {
		Map<String, Object> resultMap = getResultMap();
		try {
			if( ObjectUtil.isNotEmpty(obj.getDevice_code()) && ObjectUtil.isNotEmpty(obj.getScene_id()) ){
				// 
				IotNodeInfoBO nodeInfo = ProCacheUtil.getCache(CacheName.NODEINFO_DEVICECODE, obj.getDevice_code()) ;
				if( ObjectUtil.isNotEmpty(nodeInfo)   ){
					//
					if( nodeInfo.getScene_id() != null){
						// 设备码已使用
						putStatusCode(resultMap, Code.ResponseCode.IotInfo.DEVICE_CODE_USED) ;
					}else{
						obj.setId(nodeInfo.getId());
						// id , scene_id  , device_code
						resultMap =  service.update("IotNodeInfo.update", obj);
						if(isOk(resultMap)){
							nodeInfo.setScene_id( obj.getScene_id() );
						}
					}
				}else{
					// 设备码不存在
					putStatusCode(resultMap, Code.ResponseCode.IotInfo.DEVICE_CODE_NOT_EXIST); ;
				}
			}else{
				putStatusCode(resultMap, Code.ResponseCode.SystemCode.PARAM_ERROR) ;
			}
		} catch (Exception e) {
			exception(e,resultMap, obj);
		}
		return getModelAndView(response, resultMap);
	}
	
	/**
	 * 查询单个
	 * @param response
	 * @param id
	 * @return
	 */
	@RequestMapping(method = RequestMethod.GET, value = RequestURLIOT.NodeInfo.NODE_INFO)
	public ModelAndView selectOne(HttpServletResponse response, 
			@RequestHeader(value = ResultMapUtils.USER_KEY, required = true) String userKey ,
			@RequestParam Integer id ) {
		Map<String, Object> resultMap = getResultMap();
		try {
			
			resultMap = service.selectOne("IotNodeInfo.selectOne", new IotNodeInfoBO(id)) ;
		} catch (Exception e) {
			exception(e,resultMap, id);
		}
		return getModelAndView(response, resultMap);
	}
	
	/**
	 * LPM 更新网关状态，设备在线
	 * @param response
	 * @param obj
	 * @return
	 */
	@RequestMapping(method = RequestMethod.PUT, value = RequestURLIOT.NodeInfo.NODE_STATUS_INFO)
	public ModelAndView updateNodeStatus(HttpServletResponse response, 
			@RequestBody IotNodeInfoBO obj ) {
		Map<String, Object> resultMap = getResultMap();
		try {
			resultMap = iotNodeInfoService.updateNodeStatus(obj);
		} catch (Exception e) {
			exception(e,resultMap, obj);
		}
		return getModelAndView(response, resultMap);
	}
	
	/**
	 * 更新
	 * @param response
	 * @param obj
	 * @return
	 */
	@RequestMapping(method = RequestMethod.PUT, value = RequestURLIOT.NodeInfo.NODE_INFO)
	public ModelAndView update(HttpServletResponse response, 
			@RequestHeader(value = ResultMapUtils.USER_KEY, required = true) String userKey ,
			@RequestBody IotNodeInfoBO obj ) {
		Map<String, Object> resultMap = getResultMap();
		try {
			UserInfoBO user = getUserInfoByUserKey(userKey);
			if( ! verifyUserRole(userKey, Code.UserType.SUPER) ){
				obj.setUser_id(user.getId());				
			}
			obj.setCq_update_by(user.getName());
			resultMap = service.update("IotNodeInfo.update", obj) ;
			// 更新网关下传感器的经纬度数值
			IotSensorInfoBO iotSensorInfoBo = new IotSensorInfoBO();
			iotSensorInfoBo.setNode_id(obj.getId());
			iotSensorInfoBo.setIot_sensor_type(CodeIot.SENSOR_TYPE.POSITION);
			iotSensorInfoBo.setStr_sdata(obj.getLonLat());
			service.update("IotSensorInfo.updateSensorBySelf", iotSensorInfoBo);
			if(isOk(resultMap)){
				// 更新device
				IotNodeInfoBO pre = ProCacheUtil.getCache(CacheName.NODEINFO, obj.getId().toString());
				ProCacheUtil.addCache(CacheName.NODEINFO, obj.getId().toString(), obj);
				if(ObjectUtil.isEmpty(obj.getDevice_code())){
					// 这边是迁移设备到其他项目中
					pre.setScene_id( obj.getScene_id() );
				}else{
					if(pre.getDevice_code().equals(obj.getDevice_code())){
						ProCacheUtil.addCache(CacheName.NODEINFO_DEVICECODE, obj.getDevice_code(), obj);	
					}else{
						ProCacheUtil.addCache(CacheName.NODEINFO_DEVICECODE, obj.getDevice_code(), obj);
						ProCacheUtil.removeCache(CacheName.NODEINFO_DEVICECODE, pre.getDevice_code());
					}
					
					if(  obj.getIot_node_type()+0 == 83  ){
						// 修改网关信息后，则设置设备重新连接  TCP协议
						ProtocolUtil.sendGatewayRestart(obj) ;											
					}
				}
			}
		} catch (Exception e) {
			exception(e,resultMap, obj);
		}
		return getModelAndView(response, resultMap);
	}
	
	/**
	 * 设备excel导入
	 */
	@RequestMapping(method = RequestMethod.POST, value = "/node/upload")
	public ModelAndView upload(HttpServletResponse response,
			@RequestParam(required = false,value="type") String type,
			@RequestParam(required = false,value="property") String[] property,
			@RequestParam(required = false, value = "file") MultipartFile file) {
		Map<String, Object> resultMap = getResultMap();
		try {
			resultMap = iotNodeInfoService.importTemplateNodeInfo(file);
		} catch (Exception e) {
			super.exception(e, resultMap, file);
		}
		return  getModelAndView(response, resultMap);
	}
	
	/**
	 * 检索设备下的传感器列表，这个是全部检索，没有分页功能
	 * @param response
	 * @param 
	 * @return
	 */
	@RequestMapping(method = RequestMethod.POST, value = RequestURLIOT.NodeInfo.NODE_INFO_SENSOR_INFO_PAGE)
	public ModelAndView selectNodeSensorListPage(HttpServletResponse response, 
			@RequestHeader(value = ResultMapUtils.USER_KEY, required = true) String userKey ,
			@RequestBody IotNodeInfoBO obj) {
		Map<String, Object> resultMap = getResultMap();
		try {
			UserInfoBO user = getUserInfoByUserKey(userKey);
			obj.setUser_id(user.getId());

			List<IotNodeInfoBO> infoBO =(List<IotNodeInfoBO>)getData(service.selectList("IotNodeInfo.selectNodeSensorList", obj));
			if (infoBO != null && infoBO.size() > 0) {
				ProDictionaryInfoBO pro = new ProDictionaryInfoBO();
				pro.setP_code(20);
				List<ProDictionaryInfoBO> proDictionaryInfoBO = (List<ProDictionaryInfoBO>)getData(service.selectList("ProDictionaryInfo.selectPageList", pro));
				Map<String, String> map = new HashMap<String, String>();
				for (ProDictionaryInfoBO proDict : proDictionaryInfoBO) {
					map.put(proDict.getName(), proDict.getUrl());
				}
				for (IotNodeInfoBO iotNodeInfoBO : infoBO) {
					for (IotSensorInfoBO iotSensorInfoBO : iotNodeInfoBO.getIotSensorList()) {
						iotSensorInfoBO.setUrl(map.get(iotSensorInfoBO.getData().get("measure_unit_type")));
					}
				}
			}
			resultMap.put(ResultMapUtils.PLAT_REPONSE_DATA, infoBO);
		} catch (Exception e) {
			exception(e,resultMap, obj);
		}
		return getModelAndView(response, resultMap);
	}
	
	/**
	 * 增加设备列表，支持分页
	 */
	@RequestMapping(method = RequestMethod.POST, value = RequestURLIOT.NodeInfo.NODE_INFO_SENSOR_INFO_PAGES)
	public ModelAndView selectNodeSensorListPages(HttpServletResponse response, 
			@RequestHeader(value = ResultMapUtils.USER_KEY, required = true) String userKey ,
			@RequestParam(required=false) Integer pageSize ,
			@RequestParam Integer paged,
			@RequestBody IotNodeInfoBO obj) {
		Map<String, Object> resultMap = getResultMap();
		try {
			UserInfoBO user = getUserInfoByUserKey(userKey);
			obj.setUser_id(user.getId());
			resultMap = service.selectPageList("IotNodeInfo.selectNodeSensorList",getPageBean(paged,pageSize), obj);
		} catch (Exception e) {
			exception(e,resultMap, obj);
		}
		return getModelAndView(response, resultMap);
	}
	
	/**
	 * 删除
	 * @param response
	 * @param id
	 * @return
	 */
	@RequestMapping(method = RequestMethod.DELETE, value = RequestURLIOT.NodeInfo.NODE_INFO)
	public ModelAndView delete(HttpServletResponse response, 
			@RequestHeader(value = ResultMapUtils.USER_KEY, required = true) String userKey ,
			@RequestParam Integer id ) {
		Map<String, Object> resultMap = getResultMap();
		try {
			IotNodeInfoBO obj = new IotNodeInfoBO();
			if(ObjectUtil.isEmpty(id)){
				putStatusCode(resultMap, Code.ResponseCode.SystemCode.PARAM_ERROR);
			}else{
				UserInfoBO user = getUserInfoByUserKey(userKey);
				if( ! verifyUserRole(userKey,Code.UserType.SUPER) ){
					obj.setUser_id(user.getId());					
				}
				obj.setId(id);
				resultMap = service.delete("IotNodeInfo.deleteNode", obj) ;	
				if(isOk(resultMap)){
					
					// 这边再删除sensorlist 信息
					IotSensorInfoBO sensorBo = new IotSensorInfoBO() ;
					sensorBo.setNode_id(id);
					List<IotSensorInfoBO> sensors = getData( service.selectList("IotSensorInfo.select", sensorBo )) ;
					if( ObjectUtil.isNotEmpty(sensors) ){
						for(IotSensorInfoBO t : sensors){
							ProCacheUtil.removeCache(CacheName.SENSORINFO , t.getId()+"");
							ProCacheUtil.removeCache(CacheName.SENSORINFO_NSP, id+"-" +t.getSensor_device_id()+"-"+t.getPort_id() );
						}
						// 删除所有传感器
						service.delete("IotSensorInfo.deleteSensorByNodeId", sensorBo ) ;
					}
					
					// obj 获取缓存
					obj = ProCacheUtil.getCache(CacheName.NODEINFO, obj.getId().toString());
					ProCacheUtil.removeCache(CacheName.NODEINFO, obj.getId().toString());
					ProCacheUtil.removeCache(CacheName.NODEINFO_DEVICECODE, obj.getDevice_code());
				}
			}
		} catch (Exception e) {
			exception(e,resultMap, id);
		}
		return getModelAndView(response, resultMap);
	}
	
	/**
	 * 储存该设备下，设备的所有数据
	 * @param response
	 * @param userKey
	 * @param id
	 * @return
	 */
	@RequestMapping(method = RequestMethod.GET, value = RequestURLIOT.NodeInfo.NODE_DATA_SAVE)
	public ModelAndView saveNodeData(HttpServletResponse response, 
			@RequestHeader(value = ResultMapUtils.USER_KEY, required = true) String userKey ,
			@RequestParam Integer id ) {
		Map<String, Object> resultMap = getResultMap();
		try {
			// 不储存设备数据
			if(! "1".equals( ProConfig.APP_NODE_DATA_SAVE )  ){
				return getModelAndView(response, resultMap) ;
			}
			// 
			IotSensorInfoBO sensorBo = new IotSensorInfoBO();
			sensorBo.setNode_id(id);
			resultMap = service.selectList("IotSensorInfo.selectSensorList", sensorBo) ;
			if(isOk(resultMap)){
				List<IotSensorInfoBO> sensorList = getData(resultMap);
				String ids ="" , values ="" ;
				for(IotSensorInfoBO t : sensorList){
					ids += "|" + t.getId();
					values += "|" + t.getSdata()  ;
				}
				IotHistoryNodeDataBO nodeDataBo = new IotHistoryNodeDataBO() ;
				nodeDataBo.setAtime(new Date());
				nodeDataBo.setNode_id(id);
				nodeDataBo.setSensor_ids(ids.substring(1));
				nodeDataBo.setSdatas(values.substring(1));
				service.insert("IotHistoryNodeData.insert", nodeDataBo );
			}
		} catch (Exception e) {
			exception(e,resultMap, id);
		}
		return getModelAndView(response, resultMap);
	}
	
	
}
